namespace Guia.Elements
{
    using System.Windows.Automation;
    using Guia.Core;
    using Guia.Locator;

    /// <summary>
    /// Interface for the UiElements.
    /// </summary>
    public interface IUiElement
    {
        /// <summary>
        /// Gets the underlying AutomationElement of this UiElement.
        /// </summary>
        AutomationElement AutomationElement { get; }

        /// <summary>
        /// Gets the tooltip text of this UiElement.
        /// If no tooltip is defined, an empty string is returned.
        /// </summary>
        string ToolTip { get; }

        /// <summary>
        /// Gets the parent UiElement of this UiElement.
        /// </summary>
        UiElement ParentElement { get; }

        /// <summary>
        /// Gets the name of this UiElement.
        /// </summary>
        string Name { get; }

        /// <summary>
        /// Gets the AutomationId of this UiElement.
        /// </summary>
        string AutomationId { get; }

        /// <summary>
        /// Gets a value indicating whether the current element is enabled or not.
        /// </summary>
        bool IsEnabled { get; }

        /// <summary>
        /// Gets a value indicating whether IsOffscreen is true or not.
        /// </summary>
        bool IsOffscreen { get; }

        /// <summary>
        /// Gets the Window whicht contains this UiElement. 
        /// </summary>
        IWindow ParentWindow { get; }

        /// <summary>
        /// Gets all UiElement objects of the given type within this UiElement.
        /// </summary>
        /// <typeparam name="T">The desired type of the elements.</typeparam>
        /// <returns>All internal UiElements of the given type within this UiElement.</returns>
        T[] GetAll<T>() where T : UiElement;

        /// <summary>
        /// Gets the UiElement object of the given type and the given automationId within this UiElement.
        /// </summary>
        /// <typeparam name="T">The desired type of the element.</typeparam>
        /// <param name="automationId">The desired automationId of the element.</param>
        /// <returns>The internal UiElement of the given type and the given automationId within this UiElement.</returns>
        T Get<T>(string automationId) where T : UiElement;

        /// <summary>
        /// Gets the UiElement object of the given type and the given name within this UiElement.
        /// </summary>
        /// <typeparam name="T">The desired type of the element.</typeparam>
        /// <param name="name">The desired name of the element.</param>
        /// <returns>The internal UiElement of the given type and the given name within this UiElement.</returns>
        T GetByName<T>(string name) where T : UiElement;

        /// <summary>
        /// Gets the UiElement object of the given type and the given SearchCondition within this UiElement.
        /// </summary>
        /// <typeparam name="T">The desired type of the element.</typeparam>
        /// <param name="condition">The desired SearchCondition for the element.</param>
        /// <returns>The internal UiElement of the given type and the given SearchCondition within this UiElement.</returns>
        T Get<T>(SearchCondition condition) where T : UiElement;

        /// <summary>
        /// Gets all the UiElements object of the given type and the given SearchCondition within this UiElement.
        /// </summary>
        /// <typeparam name="T">The desired type of the elements.</typeparam>
        /// <param name="condition">The desired SearchCondition for the elements.</param>
        /// <returns>The internal UiElement objects of the given type and the given SearchCondition within this UiElement.</returns>
        T[] GetAll<T>(SearchCondition condition) where T : UiElement;

        /// <summary>
        /// Gets the UiElement object with the given SearchCondition within this UiElement.
        /// </summary>
        /// <param name="condition">The desired SearchCondition for the element.</param>
        /// <returns>The internal UiElement object with the given SearchCondition.</returns>
        UiElement Get(SearchCondition condition);

        /// <summary>
        /// Gets the UiElement object with the given automationId within this UiElement.
        /// </summary>
        /// <param name="automationId">
        /// The desired automationId of the element.
        /// </param>
        /// <returns>
        /// The internal UiElement with the given automationId within this UiElement.
        /// </returns>
        UiElement Get(string automationId);

        /// <summary>
        /// Gets the UiElement object with the given name within this UiElement.
        /// </summary>
        /// <param name="name">
        /// The desired name of the element.
        /// </param>
        /// <returns>
        /// The internal UiElement with the given name within this UiElement.
        /// </returns>
        UiElement GetByName(string name);

        /// <summary>
        /// Gets all the UiElement objects with the given SearchCondition within this UiElement.
        /// </summary>
        /// <param name="condition">The desired SearchCondition for the elements.</param>
        /// <returns>The internal UiElement objects with the given SearchCondition.</returns>
        UiElement[] GetAll(SearchCondition condition);

        /// <summary>
        /// Gets the defined UI Automation-Pattern from this element.
        /// </summary>
        /// <typeparam name="T">The desired UI Automation-Pattern</typeparam>
        /// <returns>The desired UI Automation-Pattern.</returns>
        /// <exception cref="OperationNotSupportedException"/>
        T GetPattern<T>() where T : BasePattern;

        /// <summary>
        /// Performs a right-click on this UiElement.
        /// </summary>
        void ClickRight();

        /// <summary>
        /// Performs a left-click on this UiElement.
        /// </summary>
        void ClickLeft();

        /// <summary>
        /// Performs a double-click on this UiElement.
        /// </summary>
        void DoubleClick();

        /// <summary>
        /// Sets the focus to this UiElement.
        /// </summary>
        void SetFocus();
    }
}